package com.zoe.onelink.auth.endpoint;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.zoe.onelink.auth.annotation.InnerUrl;
import com.zoe.onelink.auth.client.AuthRemoteClient;
import com.zoe.onelink.auth.properties.AuthProperties;
import com.zoe.onelink.common.constant.OnelinkFeignConstant;
import com.zoe.onelink.common.model.ApiResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>标题: 科室管理</p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-03-09 9:56
 */
@Slf4j
@RestController
@RequestMapping("/api/oauth")
@RequiredArgsConstructor
@Api(tags = "Authorize")
@InnerUrl
public class OAuthEndPoint {

    private final AuthProperties authProperties;

    private static AuthRemoteClient authRemoteClient;

    private static final String REST_TEMPLATE_PARAM_NAME = "resp";

    private static final String REST_TEMPLATE_PARAM_VALUE = "rt";

    static {
        try{
            authRemoteClient = SpringUtil.getBean(AuthRemoteClient.class);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @ApiOperation("Authorize")
    @GetMapping("/authorize")
    public ApiResult login(
            @RequestParam("username") @ApiParam(value = "用户名", required = true) String username,
            @RequestParam("password") @ApiParam(value = "密码", required = true) String password) {
        ApiResult apiResult = null;

        if (authRemoteClient == null && StrUtil.isEmpty(authProperties.getKnife4jAuthUrl())) {
            return ApiResult.success("请配置onelink.auth.knife4jAuthUrl来手动指定knife4j的授权认证地址");
        }
        // 未指定授权地址的，通过nacos取授权地址
        if(StrUtil.isEmpty(authProperties.getKnife4jAuthUrl())) {
            apiResult = authRemoteClient.auth(username, getEncryptPwd(password));
        }
        // 指定了授权地址的，通过以指定的url为准
        else {
            apiResult = getByCustomUrl(username, getEncryptPwd(password));
        }
        log.info("【knife4j登录认证】apiResult：{}", apiResult);
        return apiResult;
    }


    /**
     * 通过指定url进行授权认证
     * @param username
     * @param password
     * @return
     */
    private ApiResult getByCustomUrl(String username, String password) {
        String url = authProperties.getKnife4jAuthUrl() + "/oauth/token";
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("username", username);
        paramsMap.put("password", password);
        paramsMap.put(REST_TEMPLATE_PARAM_NAME, REST_TEMPLATE_PARAM_VALUE);
        log.info("【knife4j登录认证】指定了授权地址url：{}，paramMap：{}", url, paramsMap);
        String apiResultStr = HttpUtil.get(url, paramsMap);
        return JSON.parseObject(apiResultStr, ApiResult.class);
    }


    /**
     * 这里保持与前端对密码的加密算法一致
     * @param password
     * @return
     */
    private String getEncryptPwd(String password) {
        return SecureUtil.md5(password);
    }
}
